home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Applications / Eudora 1.3.1 / source / ends.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-16  |  26.7 KB  |  1,016 lines  |  [TEXT/MPS ]

  1. #define FILE_NUM 12
  2. /* Copyright (c) 1990-1992 by the University of Illinois Board of Trustees */
  3. /**********************************************************************
  4.  * initialization and cleanup
  5.  **********************************************************************/
  6. #pragma load EUDORA_LOAD
  7. #pragma segment Ends
  8.     void SettingsInit(UPtr name);
  9.     void OpenSettingsFile(UPtr name);
  10.     void FindMyDirectory(UPtr name);
  11.     void PutUpMenus(void);
  12.     void CreateBoxes(void);
  13.     void SetupInsurancePort(void);
  14.     int GetAppFileVRef(UPtr name);
  15.     void SetRunType(void);
  16.     Boolean ModernSystem(void);
  17.     void BoxFolder(long dirId,MenuHandle *menus, Str31 *badNames, short badCount,
  18.                                  UPtr newText, short *level);
  19.     void RemoveBoxMenus(void);
  20.     void MakeHmnusPurge(void);
  21.     void TrashHmnu(void);
  22.     void OpenPlugIns(void);
  23.     Boolean UsingNewTables(void);
  24. /**********************************************************************
  25.  * Initialize - set up my stuff as well as the Mac managers
  26.  **********************************************************************/
  27. void Initialize(void)
  28. {
  29.     Str63 name;
  30.     MacInitialize(16,20K);             /* initialize mac managers */
  31.     SetRunType();                             /* figure out what kind of run this is */
  32.     if (!ModernSystem()) WarnUser(OLD_SYSTEM,0);
  33.     OpenPlugIns();
  34.     FindMyDirectory(name);            /* find the mail folder */
  35.     MakeGrow(SPARE_SIZE);             /* reserve some memory for emergencies */
  36.     SetGrowZone(GrowZone);            /* let the mac know it's there */
  37.     SettingsInit(*name ? name:nil);
  38. #ifdef PERF
  39.     ThePGlobals = nil;
  40.     if (!InitPerf(&ThePGlobals,10,8,True,True,"\pCODE",0,"",False,0,0,0))
  41.         WarnUser(PERFORMANCE,1);
  42. #endif
  43.  
  44. /************************************************************************
  45.  * SettingsInit - Initialize with a settings file
  46.  ************************************************************************/
  47. void SettingsInit(UPtr name)
  48. {
  49.     Str255 scratch;
  50.     
  51.     if (CurrentSize()+10K<EstimatePartitionSize()) MemoryWarning();
  52.     POPSecure = False;
  53.     OpenSettingsFile(name);         /* open our settings file */
  54.     AlertsTimeout = PrefIsSet(PREF_AUTO_DISMISS);
  55.     UseCTB = PrefIsSet(PREF_TRANS_METHOD);
  56.     CurTrans = UseCTB ? CTBTrans : TCPTrans;
  57.     FigureOutFont();                        /* figure out what font && size to use */
  58.     CreateBoxes();                            /* create In and Out boxes, for later use */
  59.     PutUpMenus();                             /* menus */
  60.     PageSetup = nil;                        /* remind me to go get that */
  61.     TOCList = nil;                            /* no open TOC's yet */
  62.     MessList = nil;                         /* no open messages yet */
  63.     SetSendQueue();                         /* set SendQueue if there are queued messages */
  64.     EnableMenus(nil);                     /* enable appropriate items */
  65.     WrapWrong = CountResources('Rong') > 0;
  66.     GetPref(scratch,PREF_POP); UUPCIn = *scratch && scratch[1]=='!';
  67.     GetPref(scratch,PREF_SMTP); UUPCOut = *scratch && scratch[1]=='!';
  68.     LogLevel = GetRLong(PREF_STRN+PREF_LOG);
  69.     FakeTabs = PrefIsSet(PREF_TAB_IN_TEXT);
  70.     NewTables = UsingNewTables();
  71.     
  72.     if (!(MouseRgn = NewRgn())) DieWithError(MEM_ERR,MemError());
  73.     GetRString(NewLine,UseCTB ? CTB_NEWLINE : NEWLINE);
  74.  
  75. #ifndef KERBEROS
  76.     /*
  77.      * saved password?
  78.      */
  79.     if (PrefIsSet(PREF_SAVE_PASSWORD))
  80.     {
  81.         GetPref(Password,PREF_PASS_TEXT);
  82.         GetPref(SecondPass,PREF_AUXPW);
  83.     }
  84.     else
  85.         InvalidatePasswords(False,False);
  86. #endif
  87.     POPSecure = False;
  88.  
  89.     /*
  90.      * Bring Out Yer Dead!
  91.      */
  92.     RecallOpenWindows();
  93.     
  94.     /*
  95.      * run initial check
  96.      */
  97.     if (!EjectBuckaroo && GetRLong(PREF_STRN+PREF_INTERVAL) && !(CurrentModifiers()&optionKey))
  98.         CheckForMail(True);
  99. }
  100.  
  101. /************************************************************************
  102.  * UsingNewTables - are we using the new translit table scheme?
  103.  ************************************************************************/
  104. Boolean UsingNewTables(void)
  105. {
  106.     Boolean found=False;
  107.     Handle table;
  108.     short ind=0;
  109.     Str255 name;
  110.     short id;
  111.     ResType type;
  112.     
  113.     SetResLoad(False);
  114.     while (table=GetIndResource('taBL',++ind))
  115.     {
  116.         GetResInfo(table,&id,&type,&name);
  117.         if (found=(id<1001||id>1003)&&*name) break;
  118.     }
  119.     SetResLoad(True);
  120.     return(found);
  121. }
  122.  
  123. /************************************************************************
  124.  * OpenNewSettings - open a new settings file, closing things out
  125.  * properly first
  126.  ************************************************************************/
  127. void OpenNewSettings(short vRef,long dirId,UPtr name)
  128. {
  129.     Str31 folder;
  130.     short menu;
  131.     MenuHandle mHandle;
  132.     
  133.     /*
  134.      * a simulated Quit
  135.      */
  136.     DoQuit();
  137.     if (!AmQuitting) return;
  138.     Done = False;
  139.     
  140.     /*
  141.      * let's get rid of some stuff
  142.      */
  143.     RemoveBoxMenus();
  144.     for (menu=APPLE_MENU;menu<MENU_LIMIT;menu++)
  145.     {
  146.         if (mHandle=GetMHandle(menu)) DisposeMenu(mHandle);
  147.     }
  148.     ClearMenuBar();
  149.         
  150.     ZapHandle(Aliases);
  151.     
  152.     /*
  153.      * Now, point us at the right directory
  154.      */
  155.     MyVRef = vRef;
  156.     MyDirId = dirId;
  157.     HSetVol(nil,MyVRef,MyDirId);
  158.     HGetVol(folder,&MyVRef,&MyDirId);
  159.     MyVRef = GetMyWD(0,MyDirId);
  160.     
  161.     /*
  162.      * keep yer fingers crossed...
  163.      */
  164.     SettingsInit(name);
  165. }
  166.  
  167. /************************************************************************
  168.  * SetRunType - figure out from the name of the app whether we're prod-
  169.  * uction, testing, or my private version.    This is a HACK.
  170.  ************************************************************************/
  171. void SetRunType(void)
  172. {
  173. #ifdef DEBUG
  174.     Str255 appName;
  175.     short appRefNum;
  176.     Handle apParam;
  177.     
  178.     GetAppParms(appName,&appRefNum,&apParam);
  179.     
  180.     switch (appName[1])
  181.     {
  182.         case 'P': RunType=Steve;break;
  183.         case 'e': RunType=Debugging;break;
  184.         default: RunType=Production;break;
  185.     }
  186. #else
  187.     RunType=Production;
  188. #endif DEBUG
  189. }
  190.  
  191. /**********************************************************************
  192.  * do what we need before exiting functions
  193.  **********************************************************************/
  194. void Cleanup()
  195. {
  196. #ifdef    KERBEROS
  197.                 extern void         cplus_cleanup();
  198. #endif
  199.     TrashHmnu();
  200.     if (SettingsRefN) CloseResFile(SettingsRefN);
  201.     (void) CloseResolver();
  202.     if (DestroyTrans) (void) DestroyTrans();
  203. #ifndef SLOW_CLOSE
  204.     TcpFastFlush(True);
  205. #endif
  206.     CloseLog();
  207.     FlushVol(nil,MyVRef);
  208. #ifdef    KERBEROS
  209.                 cplus_cleanup();
  210. #endif
  211. #ifdef PERF
  212.     {
  213.         int err;
  214.         if (err=PerfDump(ThePGlobals,"\pPerform.Out",False,0))
  215.             WarnUser(PERFORMANCE,err);
  216.         TermPerf(ThePGlobals);
  217.     }
  218. #endif
  219. }
  220.  
  221.  
  222. /**********************************************************************
  223.  * figure out what font and size to use
  224.  **********************************************************************/
  225. void FigureOutFont()
  226. {
  227.     Str255 fontName;
  228.     Str255 applFontName;
  229.     Str255 fontSizeStr;
  230.     long aLong;
  231.     
  232.     /*
  233.      * which font?
  234.      */
  235.     if (IUEqualString(GetPref(fontName,PREF_FONT_NAME),
  236.                         GetRString(applFontName,APPL_FONT)) ==0)
  237.         FontID = 1;
  238.     else
  239.         FontID = GetFontID(fontName);
  240.         
  241.     /*
  242.      * how big?
  243.      */
  244.     StringToNum(GetPref(fontSizeStr,PREF_FONT_SIZE),&aLong);
  245.     FontSize = aLong;
  246.     
  247.     /*
  248.      * and how big is big?
  249.      */
  250.     FontWidth = GetWidth(FontID,FontSize);
  251.     FontLead = GetLeading(FontID,FontSize);
  252.     FontDescent = GetDescent(FontID,FontSize);
  253.     FontAscent = GetAscent(FontID,FontSize);
  254.     FontIsFixed = IsFixed(FontID,FontSize);
  255.     
  256.     /*
  257.      * and get the widths of boxes
  258.      */
  259.     GetBoxLines();
  260.     
  261.     /*
  262.      * create a spare port for necessities
  263.      */
  264.     SetupInsurancePort();
  265. }
  266.  
  267. /**********************************************************************
  268.  * open (or create) the settings file
  269.  **********************************************************************/
  270. void OpenSettingsFile(UPtr name)
  271. {
  272.     Str255 settingsName;
  273.     Handle appVersion;
  274.     Handle prefVersion;
  275.     short appRefN;
  276.     int err;
  277.     FInfo info;
  278.     
  279.     /*
  280.      * close it if it's open
  281.      */
  282.     if (SettingsRefN) CloseResFile(SettingsRefN);
  283.     
  284.     /*
  285.      * we'll create it before we open it, to avoid the PMSP
  286.      */
  287.     if (name && *name && !HGetFInfo(MyVRef,MyDirId,name,&info) && 
  288.             info.fdType==SETTINGS_TYPE && info.fdCreator==CREATOR)
  289.         PCopy(settingsName,name);
  290.     else GetRString(settingsName,SETTINGS_FILE);
  291.     if (err=MakeResFile(settingsName,MyVRef,MyDirId,CREATOR,SETTINGS_TYPE))
  292.         DieWithError(CREATE_SETTINGS,err);
  293.     
  294.     /*
  295.      * grab some stuff from the application resource file first
  296.      */
  297.     if ((appVersion = GetResource(CREATOR,1))==nil)
  298.         DieWithError(READ_SETTINGS,ResError());
  299.     appRefN = HomeResFile(appVersion);
  300.     
  301.     /*
  302.      * now, open the preferences file
  303.      */
  304.     if ((SettingsRefN=OpenResFile(settingsName))==nil)
  305.         DieWithError(OPEN_SETTINGS,ResError());
  306.         
  307.     /*
  308.      * copy the preferences into it if need be
  309.      * "need be" means either the resources aren't now there,
  310.      * or the program version has changed since last time the
  311.      * preferences file was written.
  312.      */
  313.     if ((prefVersion = GetResource(CREATOR,1))==nil)
  314.         DieWithError(READ_SETTINGS,ResError());
  315.         
  316.     if (HomeResFile(prefVersion)!=SettingsRefN ||
  317.             !EqualString(*prefVersion,*appVersion,False,False))
  318.     {
  319.         ReleaseResource(prefVersion);
  320.         if (err=ResourceCpy(SettingsRefN,appRefN,CREATOR,1))
  321.             DieWithError(WRITE_SETTINGS,err);
  322.         if (err=ResourceCpy(SettingsRefN,appRefN,'STR#',PREF_STRN))
  323.             DieWithError(WRITE_SETTINGS,err);
  324.         UpdateResFile(SettingsRefN);
  325.         if (ResError()) DieWithError(WRITE_SETTINGS,ResError());
  326.     }
  327.     else
  328.     {
  329.         ReleaseResource(prefVersion);
  330.         ReleaseResource(appVersion);
  331.     }
  332. }
  333.  
  334. /**********************************************************************
  335.  * FindMyDirectory - find the directory for us in the system folder.
  336.  * If it doesn't exist, create it.
  337.  **********************************************************************/
  338. void FindMyDirectory(UPtr name)
  339. {
  340.     DirInfo myDI;
  341.     Str31 folder;
  342.     int err=0;
  343.     SysEnvRec env;
  344.     
  345.     MyDirId = 0;
  346.     *folder = 0;
  347.     if (!(MyVRef = GetAppFileVRef(name)))
  348.     {
  349.         SysEnvirons(ENVIRONS_VERSION,&env);
  350.         
  351.         /*
  352.          * now, look for our directory
  353.          */
  354. #ifdef DEBUG
  355.         GetRString(folder,RunType==Steve ? STEVE_FOLDER : FOLDER_NAME);
  356. #else
  357.         GetRString(folder,FOLDER_NAME);
  358. #endif DEBUG
  359.         myDI.ioNamePtr = folder;
  360.         myDI.ioVRefNum = MyVRef = env.sysVRefNum;
  361.         myDI.ioFDirIndex = 0;
  362.         myDI.ioDrDirID = 0;
  363.         err=PBGetCatInfo(&myDI,False);
  364.         if (err==fnfErr)                                /* it doesn't exist */
  365.         {     
  366.             if (err=DirCreate(MyVRef,0,folder,&MyDirId))
  367.                 DieWithError(CREATE_FOLDER,err);
  368.         }
  369.         else if (myDI.ioFlAttrib&0x10)
  370.             MyDirId = myDI.ioDrDirID;
  371.         else
  372.             DieWithError(NO_PLAIN_OPEN,0);
  373.     }
  374.     if (err) DieWithError(MAIL_FOLDER,err);
  375.     if (HSetVol(folder,MyVRef,MyDirId))
  376.         HSetVol(nil,MyVRef,MyDirId);
  377.     HGetVol(folder,&MyVRef,&MyDirId);
  378.     MyVRef = GetMyWD(0,MyDirId);
  379. }
  380.     
  381. /**********************************************************************
  382.  * PutUpMenus - set up the menu bar
  383.  **********************************************************************/
  384. void PutUpMenus()
  385. {
  386.     int menu;
  387.     MenuHandle mHandle,savedMHandle;
  388.     Boolean touchedTo = False;
  389.     Str63 scratch;
  390.     
  391.     /*
  392.      * add the standard ones
  393.      */
  394.     for (menu=APPLE_MENU;menu<MENU_LIMIT;menu++)
  395.     {
  396.         if (mHandle=GetMHandle(menu)) DisposeMenu(mHandle);
  397.         mHandle = GetMenu(menu+1000);
  398.         if (mHandle==nil)
  399.             DieWithError(GET_MENU,MemError());
  400.         InsertMenu(mHandle,0);
  401.     }
  402.     if (mHandle=GetMHandle(WINDOW_MENU)) DisposeMenu(mHandle);
  403.     mHandle = GetMenu(WINDOW_MENU+1000);
  404.     if (mHandle==nil)
  405.         DieWithError(GET_MENU,MemError());
  406.     InsertMenu(mHandle,0);
  407. #ifdef DEBUG
  408.     if (RunType!=Production) InsertMenu(GetMenu(DEBUG_MENU+1000),0);
  409. #endif
  410.     
  411.     /*
  412.      * take care of special menus
  413.      */
  414.     mHandle = GetMHandle(APPLE_MENU);
  415.     AddResMenu(mHandle,'DRVR');
  416.     BuildBoxMenus();                        /* build the menus that refer to Mailboxes */
  417.  
  418.     /*
  419.      * the user menus
  420.      */
  421.     AttachHierMenu(MESSAGE_MENU,MESSAGE_NEW_TO_ITEM,NEW_TO_HIER_MENU);
  422.     AttachHierMenu(MESSAGE_MENU,MESSAGE_REPLY_TO_ITEM,REPLY_TO_HIER_MENU);
  423.     AttachHierMenu(MESSAGE_MENU,MESSAGE_FORWARD_TO_ITEM,FORWARD_TO_HIER_MENU);
  424.     AttachHierMenu(MESSAGE_MENU,MESSAGE_REDIST_TO_ITEM,REDIST_TO_HIER_MENU);
  425.     AttachHierMenu(EDIT_MENU,EDIT_INSERT_TO_ITEM,INSERT_TO_HIER_MENU);
  426.     AttachHierMenu(SPECIAL_MENU,SPECIAL_REMOVE_TO_ITEM,REMOVE_TO_HIER_MENU);
  427.     if (!(savedMHandle = GetMenu(NEW_TO_HIER_MENU+1000)))
  428.     {
  429.         if (savedMHandle = GetMenu(NEW_TO_HIER_MENU+900))
  430.         {
  431.              SetResInfo(savedMHandle,NEW_TO_HIER_MENU+1000,"");
  432.              touchedTo = True;
  433.         }
  434.         else
  435.         {
  436.             if (savedMHandle = NewMenu(NEW_TO_HIER_MENU,""))
  437.             {
  438.                 MyAppendMenu(savedMHandle,GetRString(scratch,S_DORNER));
  439.                 AddResource(savedMHandle,'MENU',NEW_TO_HIER_MENU+1000,"");
  440.                 touchedTo = True;
  441.             }
  442.             else
  443.                 DieWithError(GET_MENU,MemError());
  444.         }
  445.     }
  446.     for (menu=NEW_TO_HIER_MENU;menu<=INSERT_TO_HIER_MENU;menu++)
  447.     {
  448.         mHandle = savedMHandle;
  449.         if (menu>NEW_TO_HIER_MENU) HandToHand(&mHandle);
  450.         if (mHandle!=nil)
  451.         {
  452.             (*mHandle)->menuID=menu;
  453.             InsertMenu(mHandle,-1);
  454.         }
  455.         else
  456.             DieWithError(GET_MENU,MemError());
  457.     }
  458.     if (touchedTo) ToMenusChanged();
  459.     
  460.     /*
  461.      * hier menus
  462.      */
  463.     mHandle = GetMenu(FIND_HIER_MENU+1000);
  464.     if (mHandle==nil) DieWithError(GET_MENU,menu);
  465.     InsertMenu(mHandle,-1);
  466.     mHandle = GetMenu(SORT_HIER_MENU+1000);
  467.     if (mHandle==nil) DieWithError(GET_MENU,menu);
  468.     InsertMenu(mHandle,-1);
  469.     
  470.     /*
  471.      * draw the menu bar
  472.      */
  473.     DrawMenuBar();
  474.     
  475.     /*
  476.      * install the menuhook
  477.      */
  478. #ifdef DEBUG
  479.     if (RunType != Production)
  480.         *(long *) 0xa30 = (long)Hook;
  481. #endif
  482. }
  483.  
  484. /**********************************************************************
  485.  * BuildBoxMenus - build the mailbox menus according to the files in
  486.  * our mailbox folder.
  487.  **********************************************************************/
  488. void BoxFolder(long dirId,MenuHandle *menus,Str31 *badNames, short badCount,
  489.                              UPtr newText, short *level)
  490. {
  491.     typedef struct
  492.         {Str31 name; Boolean isDir; long dirId;} NameType, *NamePtr, **NameHandle;
  493.     HFileInfo hfi;
  494.     NameType thisOne;
  495.     NameHandle names;
  496.     short count=0,i,item,dirItem;
  497.     MenuHandle newMenus[MENU_ARRAY_LIMIT];
  498.     Str31 namePtrFodder;
  499.     Str15 suffix;
  500.     Str15 tmpsuffix;
  501.     
  502.     /*
  503.      * make sure we're kosher
  504.      */
  505.     if (*level>MAX_BOX_LEVELS)
  506.         DieWithError(TOO_MANY_LEVELS,*level);
  507.     PtrAndHand(&dirId,BoxMap,sizeof(long));
  508.  
  509.     /*
  510.      * get started
  511.      */
  512.     if ((names=NuHandle(0L))==nil)
  513.         DieWithError(ALLO_MBOX_LIST,MemError());
  514.     hfi.ioNamePtr = namePtrFodder;
  515.     hfi.ioFDirIndex = 0;
  516.     GetRString(suffix,TOC_SUFFIX);
  517.     GetRString(tmpsuffix,TEMP_SUFFIX);
  518.     /*
  519.      * read names of mailbox files
  520.      */
  521.     while (!DirIterate(MyVRef,dirId,&hfi))
  522.     {
  523.         if (dirId==MyDirId)
  524.             for (i=0;i<badCount;i++)
  525.                 if (EqualString(badNames[i],hfi.ioNamePtr,False,True)) goto nextfile;
  526.         if (!(hfi.ioFlAttrib&0x10))
  527.         {
  528.             if (hfi.ioFlFndrInfo.fdType!=MAILBOX_TYPE) continue;
  529.             if (*hfi.ioNamePtr>*tmpsuffix && EndsWith(hfi.ioNamePtr,tmpsuffix))
  530.                 TempWarning(hfi.ioNamePtr);
  531.             if (*hfi.ioNamePtr>31-*suffix)
  532.             {
  533.                 TooLong(hfi.ioNamePtr);
  534.                 continue;
  535.             }
  536.         }
  537.         PCopy(thisOne.name,hfi.ioNamePtr);
  538.         thisOne.isDir = hfi.ioFlAttrib&0x10;
  539.         thisOne.dirId = hfi.ioDirID;
  540.         PtrAndHand (&thisOne,names,sizeof(thisOne));
  541.         if (MemError()) DieWithError(ALLO_MBOX_LIST,MemError());
  542.         count++;
  543.         nextfile:;
  544.     }
  545.     
  546.     /*
  547.      * add the New item
  548.      */
  549.  AppendMenu(menus[TRANSFER],newText);
  550.  
  551.     /*
  552.      * stick them into the proper menus
  553.      */
  554.     for (item=0;item<count;item++)
  555.     {
  556.         thisOne = (*names)[item];
  557.         if (thisOne.isDir) continue;
  558.         MyAppendMenu(menus[MAILBOX],thisOne.name);
  559.         GetRString(thisOne.name,TRANSFER_PREFIX);
  560.         PCat(thisOne.name,(*names)[item].name);
  561.         MyAppendMenu(menus[TRANSFER],thisOne.name);
  562.     }
  563.     for (item=0;item<count;item++)
  564.     {
  565.         thisOne = (*names)[item];
  566.         if (!thisOne.isDir) continue;
  567.         MyAppendMenu(menus[MAILBOX],thisOne.name);
  568.         GetRString(thisOne.name,TRANSFER_PREFIX);
  569.         PCat(thisOne.name,(*names)[item].name);
  570.         MyAppendMenu(menus[TRANSFER],thisOne.name);
  571.         thisOne = (*names)[item];
  572.         for (i=0;i<MENU_ARRAY_LIMIT;i++)
  573.         {
  574.             dirItem = i*MAX_BOX_LEVELS+*level+1;
  575.             if (!(newMenus[i] = NewMenu(dirItem,thisOne.name)))
  576.                 DieWithError(ALLO_MBOX_LIST,MemError());
  577.             AttachHierMenu((*menus[i])->menuID,CountMItems(menus[i]),dirItem);
  578.             InsertMenu(newMenus[i],-1);
  579.             if (HasHelp && *level && !Get1Resource('hmnu',dirItem))
  580.             {
  581.                 Handle mHand=GetResource('hmnu',i*MAX_BOX_LEVELS+1);
  582.                 Handle newHand=mHand;
  583.                 if (mHand && !HandToHand(&newHand))
  584.                 {
  585.                     AddResource(newHand,'hmnu',dirItem,"");
  586.                     SetResAttrs(newHand,resChanged|resPurgeable);
  587.                 }
  588.             }
  589.         }
  590.         (*level)++;
  591.         BoxFolder(thisOne.dirId,newMenus,badNames,badCount,newText,level);
  592.         if (MemError()) DieWithError(ALLO_MBOX_LIST,MemError());
  593.     }
  594.     DisposHandle(names);
  595. }
  596.  
  597. /************************************************************************
  598.  * TempWarning - warn the user about a temp file in his mailbox structure
  599.  ************************************************************************/
  600. void TempWarning(UPtr filename)
  601. {
  602.     Str255 msg;
  603.     GetRString(msg,TEMP_WARNING);
  604.     MyParamText(msg,filename,"","");
  605.     ReallyDoAnAlert(OK_ALRT,Caution);
  606. }
  607.  
  608. /**********************************************************************
  609.  * BuildBoxMenus - build the mailbox menus according to the files in
  610.  * our mailbox folder.
  611.  **********************************************************************/
  612. void BuildBoxMenus()
  613. {
  614.     short badIndices[] = {IN,OUT,ALIAS_FILE,TRASH,LOG_NAME,OLD_LOG};
  615.     Str31 badNames[sizeof(badIndices)/sizeof(short)];
  616.     Str31 newText;
  617.     MenuHandle menus[MENU_ARRAY_LIMIT];
  618.     short level=0,i;
  619.     
  620.     if (BoxMap!=nil) RemoveBoxMenus();
  621.     if ((BoxMap=NuHandle(0L))==nil)
  622.         DieWithError(ALLO_MBOX_LIST,MemError());
  623.     for (i=0;i<sizeof(badIndices)/sizeof(short);i++)
  624.       GetRString(badNames[i],badIndices[i]);
  625.     GetRString(newText,NEW_ITEM_TEXT);
  626.             
  627.     /*
  628.      * stick them into the proper menus
  629.      */
  630.     menus[MAILBOX] = GetMHandle(MAILBOX_MENU);
  631.     menus[TRANSFER] = GetMHandle(TRANSFER_MENU);
  632.     
  633.     /*
  634.      * now, do the recursive thing
  635.      */
  636.     BoxFolder(MyDirId,menus,badNames,sizeof(badNames)/sizeof(Str31),
  637.                         newText,&level);
  638.     if (HasHelp) MakeHmnusPurge();
  639.     BuildBoxCount();
  640.     DrawMenuBar();
  641. }
  642.  
  643. /************************************************************************
  644.  * RemoveBoxMenus - get a clean slate
  645.  ************************************************************************/
  646. void RemoveBoxMenus(void)
  647. {
  648.     DisposHandle(BoxMap); BoxMap = nil;
  649.     TrashHmnu();
  650.     CheckBox(nil);
  651.     TrashMenu(GetMHandle(MAILBOX_MENU),MAILBOX_BAR1_ITEM+1);
  652.     TrashMenu(GetMHandle(TRANSFER_MENU),TRANSFER_NEW_ITEM);
  653. }
  654.  
  655. /************************************************************************
  656.  * TrashHmnu - get rid of the help resources for subfolders
  657.  ************************************************************************/
  658. void TrashHmnu(void)
  659. {
  660.     short i,n;
  661.     Handle hHand;
  662.     
  663.     n = GetHandleSize(BoxMap)/sizeof(long);
  664.     SetResLoad(False);
  665.     for (i=2;i<=n;i++)
  666.     {
  667.         if (hHand=Get1Resource('hmnu',i))
  668.         {
  669.             RmveResource(hHand);
  670.             DisposHandle(hHand);
  671.         }
  672.         if (hHand=Get1Resource('hmnu',i+MAX_BOX_LEVELS))
  673.         {
  674.             RmveResource(hHand);
  675.             DisposHandle(hHand);
  676.         }
  677.     }
  678.     SetResLoad(True);
  679.     UpdateResFile(CurResFile());
  680. }
  681.  
  682. /************************************************************************
  683.  * MakeHmnusPurge - make sure we can purge the Hmnus
  684.  ************************************************************************/
  685. void MakeHmnusPurge(void)
  686. {
  687.     short i,n;
  688.     Handle hHand;
  689.     
  690.     /*
  691.      * first off, get them written out
  692.      */
  693.     UpdateResFile(CurResFile());
  694.     
  695.     /*
  696.      * trash 'em
  697.      */
  698.     n = GetHandleSize(BoxMap)/sizeof(long);
  699.     SetResLoad(False);
  700.     for (i=1;i<=n;i++)
  701.     {
  702.         if (hHand=Get1Resource('hmnu',i))
  703.             ReleaseResource(hHand);
  704.         if (hHand=Get1Resource('hmnu',i+MAX_BOX_LEVELS))
  705.             ReleaseResource(hHand);
  706.     }
  707.     SetResLoad(True);
  708. }
  709.  
  710. /************************************************************************
  711.  * TrashMenu - get rid of a menu, beginning at a particular item
  712.  ************************************************************************/
  713. void TrashMenu(MenuHandle mh, short beginAtItem)
  714. {
  715.     short count,id,item;
  716.     MenuHandle subMh;
  717.     
  718.     if (!mh) return;
  719.     for (count=CountMItems(mh),item=beginAtItem?beginAtItem:1;item<=count;item++)
  720.         if (HasSubmenu(mh,item))
  721.         {
  722.             GetItemMark(mh,item,&id);
  723.             subMh = GetMHandle(id);
  724.             TrashMenu(subMh,0);
  725.             SetItemCmd(mh,item,0);
  726.             DeleteMenu(id);
  727.             DisposeMenu(subMh);
  728.         }
  729.     if (beginAtItem>0)
  730.         while (count>=beginAtItem) DelMenuItem(mh,count--);
  731. }
  732.  
  733. /**********************************************************************
  734.  * CreateBoxes - Create the "In" and "Out" mailboxes if need be
  735.  **********************************************************************/
  736. void CreateBoxes()
  737. {
  738.     Str63 name;
  739.     int err;
  740.     
  741.     GetRString(name,IN);
  742.     if (err=MakeResFile(name,MyVRef,MyDirId,CREATOR,MAILBOX_TYPE))
  743.         DieWithError(CREATING_MAILBOX,err);
  744.     GetRString(name,OUT);
  745.     if (err=MakeResFile(name,MyVRef,MyDirId,CREATOR,MAILBOX_TYPE))
  746.         DieWithError(CREATING_MAILBOX,err);
  747.     GetRString(name,TRASH);
  748.     if (err=MakeResFile(name,MyVRef,MyDirId,CREATOR,MAILBOX_TYPE))
  749.         DieWithError(CREATING_MAILBOX,err);
  750.     GetRString(name,ALIAS_FILE);
  751.     if (err=MakeResFile(name,MyVRef,MyDirId,CREATOR,'TEXT'))
  752.         DieWithError(CREATING_ALIAS,err);
  753. }
  754.  
  755. /**********************************************************************
  756.  * GetBoxLines - read the horizontal widths of the various mailbox
  757.  * data areas.
  758.  **********************************************************************/
  759. void GetBoxLines(void)
  760. {
  761.     Handle strn;
  762.     int count;
  763.     Str255 scratch;
  764.     long rightSide;
  765.     short last=0;
  766.     short offset=0;
  767.     short i;
  768.     
  769.     strn=GetResource('STR#',BOX_LINES_STRN);
  770.     if (strn==nil) DieWithError(GENERAL,ResError());
  771.     
  772.     count = *((short *)*strn);
  773.     
  774.     if (!BoxLines) BoxLines = NuHandle(count*sizeof(short));
  775.     if (BoxLines==nil) DieWithError(MEM_ERR,MemError());
  776.     
  777.     for(i=0;i<count;i++)
  778.     {
  779.         StringToNum(GetRString(scratch,BOX_LINES_STRN+i+1),&rightSide);
  780.         if (rightSide<=last) {rightSide=last; offset+=3;}    /* for zero, make 3 pixels */
  781.         last = rightSide;
  782.         (*BoxLines)[i] = FontWidth*rightSide+offset;
  783.     }
  784. }
  785.  
  786. /************************************************************************
  787.  * SetSendQueue - preload the SendQueue global with the number of queued
  788.  * messages.
  789.  ************************************************************************/
  790. void SetSendQueue(void)
  791. {
  792.     TOCType **tocH;
  793.     int sumNum;
  794.     uLong gmtSecs = GMTDateTime();
  795.     
  796.     SendQueue = 0;
  797.     ForceSend = 0xffffffff;
  798.     if (!(tocH=GetOutTOC())) return;
  799.     for (sumNum=0; sumNum<(*tocH)->count; sumNum++)
  800.         if ((*tocH)->sums[sumNum].state == QUEUED)
  801.         {
  802.           if ((*tocH)->sums[sumNum].seconds &&
  803.                 (*tocH)->sums[sumNum].seconds < ForceSend)
  804.                 ForceSend = (*tocH)->sums[sumNum].seconds;
  805.           if ((*tocH)->sums[sumNum].seconds <= gmtSecs) SendQueue++;
  806.         }
  807. }
  808.  
  809. /************************************************************************
  810.  * SetupInsurancePort - create a grafport for use when others are unavailable
  811.  ************************************************************************/
  812. void SetupInsurancePort(void)
  813. {
  814.     if (!InsurancePort)
  815.     {
  816.         InsurancePort = New(GrafPort);
  817.         if (!InsurancePort) DieWithError(MEM_ERR,MemError());
  818.         OpenPort(InsurancePort);
  819.     }
  820.     SetPort(InsurancePort);
  821.     TextFont(FontID);
  822.     TextSize(FontSize);
  823. }
  824.  
  825. /************************************************************************
  826.  * GetAppFileVRef - get the vrefn of the file that launched us
  827.  ************************************************************************/
  828. int GetAppFileVRef(UPtr name)
  829. {
  830.     short message,count;
  831.     AppFile aFile;
  832.     
  833.     *name = 0;
  834.     CountAppFiles(&message,&count);
  835.     if (!count) return(0);
  836.     
  837.     GetAppFiles(1,&aFile);
  838.     PCopy(name,aFile.fName);
  839.     return(aFile.vRefNum);
  840. }
  841.  
  842. /************************************************************************
  843.  * ModernSystem - is the system 6.0.4 or better?
  844.  ************************************************************************/
  845. Boolean ModernSystem(void)
  846. {
  847.     SysEnvRec env;
  848.     long resp;
  849.  
  850.     HasHelp = !Gestalt(gestaltHelpMgrAttr,&resp) &&
  851.                                         resp&(1L<<gestaltHelpMgrPresent);
  852.     HasPM = !Gestalt(gestaltOSAttr,&resp) && resp&(1L<<gestaltLaunchControl);
  853.     if (HasPM && !Gestalt(gestaltAUXVersion, &resp))
  854.         HasPM = (resp>>8)>=3;
  855.     SysEnvirons(ENVIRONS_VERSION,&env);
  856.     return(env.systemVersion >= 0x0604);
  857. }
  858.  
  859. typedef struct
  860. {
  861.     short wType;                    /* window type */
  862.     long dirId;                     /* if any */
  863.     short index;                    /* if any */
  864.     Str31 volName;                /* if any */
  865.     Str31 name;                     /* if any */
  866.     Str31 alias;                    /* if any */
  867. } DejaVu, **DejaVuPtr, **DejaVuHandle;
  868. #define DEJA_VU_TYPE 'dJvU'
  869.  
  870. void RememberOpenWindows(void)
  871. {
  872.     DejaVuHandle dvh;
  873.     DejaVu dv;
  874.     short ind;
  875.     MyWindowPtr win;
  876.     TOCHandle tocH;
  877.     MessHandle messH;
  878.     TextDHandle textH;
  879.     extern FindClose();
  880.     
  881.     /*
  882.      * out with the old
  883.      */
  884.     SetResLoad(False);
  885.     while (dvh=Get1IndResource(DEJA_VU_TYPE,1))
  886.     {
  887.         RmveResource(dvh);
  888.                 DisposHandle(dvh);
  889.     }
  890.     SetResLoad(True);
  891.     
  892.     /*
  893.      * save each window
  894.      */
  895.     ind = 1000;
  896.     for (win=FrontWindow();win;win=win->qWindow.nextWindow)
  897.         if (IsMyWindow(win) && win->qWindow.visible)
  898.                 {
  899.                     dv.wType = win->qWindow.windowKind;
  900.                     if (win->close==FindClose) dv.wType = FIND_WIN;
  901.                     switch (dv.wType)
  902.                     {
  903.                         case MBOX_WIN:
  904.                         case CBOX_WIN:
  905.                             tocH = (TOCHandle) win->qWindow.refCon;
  906.                             PCopy(dv.name,(*tocH)->name);
  907.                             dv.dirId = (*tocH)->dirId;
  908.                             break;
  909.                         case MESS_WIN:
  910.                         case COMP_WIN:
  911.                             messH = (MessHandle) win->qWindow.refCon;
  912.                             tocH = (TOCHandle) (*messH)->tocH;
  913.                             PCopy(dv.name,(*tocH)->name);
  914.                             dv.index = (*messH)->sumNum;
  915.                             dv.dirId = (*tocH)->dirId;
  916.                             break;
  917.                         case TEXT_WIN:
  918.                             textH = (TextDHandle) win->qWindow.refCon;
  919.                             PCopy(dv.name,(*textH)->fileName);
  920.                             PCopy(dv.alias,*win->qWindow.titleHandle);
  921.                             GetMyVolName((*textH)->vRef,dv.volName);
  922.                             PCatC(dv.volName,':');
  923.                             dv.dirId = GetMyDirID((*textH)->vRef);
  924.                             break;
  925.                         case ALIAS_WIN:
  926.                         case MB_WIN:
  927.                         case FIND_WIN:
  928.                         case PH_WIN:
  929.                             break;
  930.                     }
  931.                     if (dvh=NuHandle(sizeof(dv)))
  932.                     {
  933.                         BlockMove(&dv,*dvh,sizeof(dv));
  934.                                 AddResource(dvh,DEJA_VU_TYPE,++ind,"");
  935.                                 ReleaseResource(dvh);
  936.                     }
  937.                 }
  938. }
  939.  
  940. /************************************************************************
  941.  * RecallOpenWindows - reopen windows there when we quit
  942.  ************************************************************************/
  943. void RecallOpenWindows(void)
  944. {
  945.     short ind;
  946.     DejaVuHandle dvh;
  947.     DejaVu dv;
  948.     TOCHandle tocH;
  949.     short vRef;
  950.     
  951.     for (ind=1000+Count1Resources(DEJA_VU_TYPE);!EjectBuckaroo && ind>1000;ind--)
  952.     {
  953.         if (dvh=Get1Resource(DEJA_VU_TYPE,ind))
  954.         {
  955.             ActivateMyWindow(FrontWindow(),False);
  956.             dv = **dvh;
  957.             ReleaseResource(dvh);
  958.             switch (dv.wType)
  959.             {
  960.                 case MBOX_WIN:
  961.                 case CBOX_WIN:
  962.                     if (FindDirLevel(dv.dirId)>=0)    /* don't open boxes not in tree */
  963.                         (void) GetMailbox(dv.dirId,dv.name,True);
  964.                     break;
  965.                 case MESS_WIN:
  966.                 case COMP_WIN:
  967.                     if (FindDirLevel(dv.dirId)>=0 &&    /* don't open boxes not in tree */
  968.                           (tocH = TOCByName(dv.dirId,dv.name)) && dv.index<(*tocH)->count)
  969.                         GetAMessage(tocH,dv.index,nil,True);
  970.                     break;
  971.                 case TEXT_WIN:
  972.                     vRef = GetMyVR(dv.volName);
  973.                     if (!OpenWD(vRef,dv.dirId,nil,&vRef))
  974.                         OpenText(vRef,dv.name,nil,True,dv.alias);
  975.                     break;
  976.                 case ALIAS_WIN:
  977.                     OpenAliases();
  978.                     break;
  979.                 case MB_WIN:
  980.                     OpenMBWin();
  981.                     break;
  982.                 case FIND_WIN:
  983.                     DoFind(FIND_FIND_ITEM);
  984.                     break;
  985.                 case PH_WIN:
  986.                     OpenPh();
  987.                     break;
  988.             }
  989.         }
  990.         MonitorGrow();
  991.     }
  992. }
  993.  
  994. /************************************************************************
  995.  * OpenPlugIns - open extra Eudora resource files
  996.  ************************************************************************/
  997. void OpenPlugIns(void)
  998. {
  999.   short vRef;
  1000.     long dirId;
  1001.     HFileInfo hfi;
  1002.     Str31 name;
  1003.   if (!FindFolder(kOnSystemDisk,kPreferencesFolderType,False,&vRef,&dirId))
  1004.     {
  1005.       hfi.ioFDirIndex = 0;
  1006.         hfi.ioNamePtr = name;
  1007.         while(!DirIterate(vRef,dirId,&hfi))
  1008.         if (hfi.ioFlFndrInfo.fdType==PLUG_TYPE &&
  1009.             hfi.ioFlFndrInfo.fdCreator==CREATOR)
  1010.         {
  1011.             if (!HOpenResFile(vRef, dirId, name, fsRdPerm))
  1012.               FileSystemError(OPEN_SETTINGS,name,ResError());
  1013.         }
  1014.     }
  1015. }